﻿using System.Collections.Generic;
using System.Reflection;
using System;
using System.Linq;

namespace UniversalApproach.Expands
{
    public static class PropertyExpand
    {
        /// <summary>
        /// 递归调用：获取复杂模型属性
        /// </summary>
        /// <param name="propertyInfos"></param>
        /// <param name="fatherPropertyName"></param>
        /// <returns></returns>
        public static List<ObjectExpand.Properties> GetProperties(PropertyInfo[] propertyInfos, string fatherPropertyName = "")
        {
            var propertiesList = new List<ObjectExpand.Properties>();

            foreach (var item in propertyInfos)
            {
                var tmpData = new ObjectExpand.Properties();
                if (item.Name == "MemberType")
                {
                    continue;
                }

                //字符串特殊处理
                if (item.PropertyType == typeof(string))
                {
                    tmpData.PropertyInfo = item;
                    tmpData.PropertyName = item.Name;
                    tmpData.IsObject = false;
                    tmpData.FatherPropertyName = fatherPropertyName;
                }
                //日期特殊处理
                else if (item.PropertyType == typeof(DateTime))
                {
                    tmpData.PropertyInfo = item;
                    tmpData.PropertyName = item.Name;
                    tmpData.IsObject = false;
                    tmpData.FatherPropertyName = fatherPropertyName;
                }
                //判断是否为对象。对象拥有多个属性
                else if (item.PropertyType.GetProperties().Length > 0)
                {
                    propertiesList.AddRange(GetProperties(item.PropertyType.GetProperties(), $"{fatherPropertyName}.{item.Name}"));
                    continue;
                }
                else
                {
                    tmpData.PropertyInfo = item;
                    tmpData.PropertyName = item.Name;
                    tmpData.IsObject = false;
                    tmpData.FatherPropertyName = fatherPropertyName;
                }

                propertiesList.Add(tmpData);
            }

            foreach (var prop in propertiesList)
            {
                var reg = new System.Text.RegularExpressions.Regex("^\\.");
                if (reg.IsMatch(prop.FatherPropertyName))
                {
                    prop.FatherPropertyName = prop.FatherPropertyName.Remove(0, 1);
                }
            }

            return propertiesList;
        }

        /// <summary>
        /// 获取复杂模型值
        /// </summary>
        /// <param name="propertyInfo"></param>
        /// <param name="source"></param>
        /// <returns></returns>
        public static object GetValue(ObjectExpand.Properties propertyInfo, object source)
        {
            //如果是深层的对象属性
            if (propertyInfo.FullName.Contains("."))
            {
                var deepName = propertyInfo.FullName.Split(new string[] { "." }, StringSplitOptions.RemoveEmptyEntries);
                return GetValueByDeep(propertyInfo, source, deepName.ToList());
            }
            else
            {
                return propertyInfo.PropertyInfo.GetValue(source, null);
            }
        }

        /// <summary>
        /// 递归调用：获取模型值
        /// </summary>
        /// <param name="properties"></param>
        /// <param name="source"></param>
        /// <param name="deepName"></param>
        /// <returns></returns>
        public static object GetValueByDeep(ObjectExpand.Properties properties, object source, List<string> deepName)
        {
            if (deepName.Count == 1)
            {
                return properties.PropertyInfo.GetValue(source, null);
            }
            else
            {
                var first = deepName.FirstOrDefault();
                var firstObjProperty = source.GetType().GetProperty(first);
                var nextSource = firstObjProperty.GetValue(source, null);
                deepName.RemoveRange(0, 1);
                return GetValueByDeep(properties, nextSource, deepName);
            }
        }
    }
}